package process;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

import javax.swing.JTextArea;

import query.AnalyzedQuestion;
import query.Query;
import query.QueryGenerationManager;
import query.QuestionAnalyzer;
import analysis.Analyzer;

public class ResultProcessManager {

	private static final boolean TESTING = false;

	static final int TERM_APPEARANCE_SCORE = 2;
	static final int EXTRA_ALLTERMS_APPEARANCE_SCORE = 5;
	static final int SAME_VERBAL_TENSE_SCORE = 1;
	static final int PATTERN_APPEARANCE_SCORE = 5;
	static final int INTERROGATIVE_PARTICLE_APPEARANCE = 3;

	public static Query query;
	public static AnsExtTesting miFrame;
	public static JTextArea jTextArea1;
	public static ArrayList<ArrayList<Result>> searchResults = new ArrayList<ArrayList<Result>>(),
			rawR = new ArrayList<ArrayList<Result>>();
	public static AnalyzedQuestion aq;
	private static QueryType[] listaObjectWorkers = new QueryType[10];

	// Objeto que hace el trabajo en función del tipo de pregunta
	private static QueryType objectWorker;

	public static void startAnswerSelection() {

		initialize();

		/*
		 * CC Coordinating conjunction CD Cardinal number DT Determiner EX
		 * Existential there FW Foreign word IN Preposition or subordinating
		 * conjunction JJ Adjective JJR Adjective, comparative JJS Adjective,
		 * superlative LS List item marker MD Modal NN Noun, singular or mass
		 * NNS Noun, plural NNP Proper noun, singular NNPS Proper noun, plural
		 * PDT Predeterminer POS Possessive ending PRP Personal pronoun PRP$
		 * Possessive pronoun RB Adverb RBR Adverb, comparative RBS Adverb,
		 * superlative RP Particle SYM Symbol TO to UH Interjection VB Verb,
		 * base form VBD Verb, past tense VBG Verb, gerund or present participle
		 * VBN Verb, past participle VBP Verb, non­3rd person singular present
		 * VBZ Verb, 3rd person singular present WDT Wh­determiner WP Wh­pronoun
		 * WP$ Possessive wh­pronoun WRB Wh­adverb
		 */

		for (int h = 0; h < searchResults.size(); h++) {

			ArrayList<Result> arrl = sentenceSplitting(searchResults.get(h));
			rawR.add(arrl);

			for (Result r : arrl) {
				//miFrame.addResultComboBox(r);
							
				if(r.getAnswer().length()>4 && answerIsNotEqualsQuestion(r,h)){
					
					if(r.getAnswer().length()>50){
						
						String[] keywords = r.getQuery().getQuestionAnalysis().getKeywords();
						int posmin = 99999;
						for(int p=0;p<keywords.length;p++){							
							int position = r.getAnswer().indexOf(keywords[p]);
							if(position<posmin && position!=-1) posmin = position;
						}
						
						if(posmin<99999){
							if(posmin>10){
								if(r.getAnswer().length()-posmin>39){
									r.setAnswer(r.getAnswer().substring(posmin-10, posmin+39));
								}
								else{
									r.setAnswer(r.getAnswer().substring(r.getAnswer().length()-50));
								}
							}
							else{
								r.setAnswer(r.getAnswer().substring(0,49));
							}
						}
						else{
							r.setAnswer(r.getAnswer().substring(0,49));
						}
						
					}
					
					String text;
					text = r.getAnswer().trim();
					text = text.replaceAll("\\s+", " ");
					text = QuestionAnalyzer.erasePunctuation(text);
	
					r.setWords(QuestionAnalyzer.getWords(text));
	
					String totalWords = "";
					for (String s : r.getWords()) {
						totalWords = totalWords + " | " + s;
					}
	
					System.out.println(" WORDS: " + totalWords);
	
					String[] tags = Analyzer.protag(r.getWords());
	
					r.setTags(tags);
	
					aq = r.getQuery().getQuestionAnalysis();
	
					// Trabajo sobre el resultado del objeto experto.
					// En Initialize defino un array con los objetos expertos parar
					// realizar el trabajo de puntuacion
					// Estos objetos estan inicializados en orden en funcion del
					// ordninal del enumerado.
					(listaObjectWorkers[aq.getType().ordinal()]).setScore(r);
				}
				else{
					r.setScore(0);
				}
			}
			orderBestAnswers();
					
								
		}
		
		miFrame = new AnsExtTesting();
		miFrame.setVisible(true);

	}

	private static boolean answerIsNotEqualsQuestion(Result r,int i) {
		boolean resp = true;
		
		ArrayList<String> questionList = QueryGenerationManager.getQuestionList();
		
		if(questionList.get(i).length()>6){
			String questionText = questionList.get(i).substring(5);
			
		    System.out.println("SUBSTRING: "+questionText);
		    
		    for(int j=0;j<=r.getAnswer().length()-questionText.length();j++){
		    	String subAnswer = r.getAnswer().substring(j);
				if(questionText.equals(subAnswer)){
					resp = false;
				}
		    }
		}
		
		return resp;
	}

	private static void orderBestAnswers() {
								
		System.out.println("VALORES!!!! rawrsize: "+rawR.size());
		
		for (int j = 0; j < rawR.size(); j++) {																		
			sort(rawR.get(j));		
			/*if(rawR.get(j).size()>10){
				for(int g=10; g <rawR.get(j).size();g++){
					rawR.get(j).remove(g);
				}
			}*/
			System.out.println("VALORES2!!!! rawrsize(j): "+rawR.get(j).size());		
		}			
		
		System.out.println("VALORES!!!! rawrsize: "+rawR.size());
			
	}
	
	 public static void sort(ArrayList<Result> vector) { 
         
	        for(int i = 0; i < vector.size(); i++){ 
	            float max = -1; 
	            int pos = 0;	            
	            for(int j=i; j < vector.size(); j++){ 
	            	if(vector.get(j).getScore()>max){
	            		max = vector.get(j).getScore();
	            		pos = j;
	            	}
	            } 
	            System.out.println("VALOR mas grande: "+vector.get(pos).getScore());
	            Result r = vector.get(pos);
	            vector.remove(pos);
	            if(r.getScore()!=0){	            		            
	            	vector.add(i,r);
	            }	            
	            
	        }         
	    }	
	 
	private static ArrayList<Result> sentenceSplitting(
			ArrayList<Result> listaResults) {

		ArrayList<Result> rawResults = new ArrayList<Result>();

		for (Result r : listaResults) {
			if (r.getScore() != Float.NEGATIVE_INFINITY) {
				String sentence = r.getAnswer();
				String[] sentences = sentence.split("\\.");
				if (sentences.length != 0) {

					// re-join cut abbreviations
					ArrayList<String> sentenceList = new ArrayList<String>();
					String sen = sentences[0];
					for (int s = 1; s < sentences.length; s++) {
						String end = sen.substring(sen.lastIndexOf(" ") + 1)
								.toLowerCase();
						if ((end.length() < 3) || end.matches("(^[aeiouy])++"))
							sen = sen + ". " + sentences[s];
						else {
							sentenceList.add(sen);
							sen = sentences[s];
						}
					}
					sentenceList.add(sen);
					sentences = sentenceList.toArray(new String[sentenceList
							.size()]);

					r.setAnswer(sentences[0]);
					rawResults.add(r);
					for (int s = 1; s < sentences.length; s++) {
						Result newRes = new Result(sentences[s], r.getQuery(),
								r.getDocID(), r.getHitPos());
						newRes.setScore(r.getScore());
						rawResults.add(newRes);

					}
				}
			}
		}

		listaResults.clear();
		for (Result r : rawResults) {
			listaResults.add(r);
		}
		rawResults.clear();

		for (Result r : listaResults) {
			if (r.getScore() != Float.NEGATIVE_INFINITY) {
				String sentence = r.getAnswer();
				String[] sentences = sentence.split("\\. \\. \\. ");
				if (sentences.length != 0) {
					r.setAnswer(sentences[0]);
					rawResults.add(r);
					for (int s = 1; s < sentences.length; s++) {
						//System.out.println("\n SPLIT ? !");
						Result newRes = new Result(sentences[s], r.getQuery(),
								r.getDocID(), r.getHitPos());
						newRes.setScore(r.getScore());
						rawResults.add(newRes);
						/*
						 * writeToTextArea("\n"); writeToTextArea(sentences[s]);
						 */
					}
				}
			}
		}

		listaResults.clear();
		for (Result r : rawResults) {
			listaResults.add(r);
		}
		rawResults.clear();	
		
		
		for (Result r : listaResults) {
			if (r.getScore() != Float.NEGATIVE_INFINITY) {
				String sentence = r.getAnswer();
				String[] sentences = sentence.split("\\?|\\!");
				if (sentences.length != 0) {
					r.setAnswer(sentences[0]);
					rawResults.add(r);
					for (int s = 1; s < sentences.length; s++) {
						//System.out.println("\n SPLIT ? !");
						Result newRes = new Result(sentences[s], r.getQuery(),
								r.getDocID(), r.getHitPos());
						newRes.setScore(r.getScore());
						rawResults.add(newRes);
						/*
						 * writeToTextArea("\n"); writeToTextArea(sentences[s]);
						 */
					}
				}
			}
		}

		listaResults.clear();
		for (Result r : rawResults) {
			listaResults.add(r);
		}
		rawResults.clear();						

		for (Result r : listaResults) {
			if (r.getScore() != Float.NEGATIVE_INFINITY) {
				String sentence = r.getAnswer();
				String[] sentences = sentence.split("\\;");
				if (sentences.length != 0) {
					r.setAnswer(sentences[0]);
					rawResults.add(r);
					for (int s = 1; s < sentences.length; s++) {
						Result newRes = new Result(sentences[s], r.getQuery(),
								r.getDocID(), r.getHitPos());
						newRes.setScore(r.getScore());
						rawResults.add(newRes);
					}
				}
			}
		}

		listaResults.clear();
		for (Result r : rawResults) {
			listaResults.add(r);
		}
		rawResults.clear();

		for (Result r : listaResults) {
			if (r.getScore() != Float.NEGATIVE_INFINITY) {
				String sentence = r.getAnswer();
				String[] sentences = sentence.split("\\-\\-");
				if (sentences.length != 0) {
					r.setAnswer(sentences[0]);
					rawResults.add(r);
					for (int s = 1; s < sentences.length; s++) {
						Result newRes = new Result(sentences[s], r.getQuery(),
								r.getDocID(), r.getHitPos());
						newRes.setScore(r.getScore());
						rawResults.add(newRes);
						/*
						 * writeToTextArea("\n"); writeToTextArea(sentences[s]);
						 */
					}
				}
			}
		}

		listaResults.clear();
		for (Result r : rawResults) {
			listaResults.add(r);
		}
		rawResults.clear();

		for (Result r : listaResults) {
			if (r.getScore() != Float.NEGATIVE_INFINITY) {
				String sentence = r.getAnswer();
				String[] sentences = sentence.split("\\.\\'\\'");
				if (sentences.length != 0) {
					r.setAnswer(sentences[0]);
					rawResults.add(r);
					for (int s = 1; s < sentences.length; s++) {
						Result newRes = new Result(sentences[s], r.getQuery(),
								r.getDocID(), r.getHitPos());
						newRes.setScore(r.getScore());
						rawResults.add(newRes);
						/*
						 * writeToTextArea("\n"); writeToTextArea(sentences[s]);
						 */
					}
				}
			}
		}		
		
		
		listaResults.clear();
		for (Result r : rawResults) {
			listaResults.add(r);
		}
		rawResults.clear();

		for (Result r : listaResults) {
			if (r.getScore() != Float.NEGATIVE_INFINITY) {
				String sentence = r.getAnswer();
				String[] sentences = sentence.split(":");
				if (sentences.length != 0) {
					r.setAnswer(sentences[0]);
					rawResults.add(r);
					for (int s = 1; s < sentences.length; s++) {
						Result newRes = new Result(sentences[s], r.getQuery(),
								r.getDocID(), r.getHitPos());
						newRes.setScore(r.getScore());
						rawResults.add(newRes);
					}
				}
			}
		}				

		return rawResults;
	}

	private static void initialize() {	

		// THING, OWNER, PERSON, PLACE, TIME, MANNER, REASON, CHOICE, NOTYPE;
		listaObjectWorkers[QuestionAnalyzer.ANSWER_TYPE.THING.ordinal()] = new TypeThingClass();
		listaObjectWorkers[QuestionAnalyzer.ANSWER_TYPE.OWNER.ordinal()] = new TypeOwnerClass();
		listaObjectWorkers[QuestionAnalyzer.ANSWER_TYPE.PERSON.ordinal()] = new TypePersonClass();
		listaObjectWorkers[QuestionAnalyzer.ANSWER_TYPE.PLACE.ordinal()] = new TypePlaceClass();
		listaObjectWorkers[QuestionAnalyzer.ANSWER_TYPE.TIME.ordinal()] = new TypeTimeClass();
		listaObjectWorkers[QuestionAnalyzer.ANSWER_TYPE.MANNER.ordinal()] = new TypeMannerClass();
		listaObjectWorkers[QuestionAnalyzer.ANSWER_TYPE.REASON.ordinal()] = new TypeReasonClass();
		listaObjectWorkers[QuestionAnalyzer.ANSWER_TYPE.CHOICE.ordinal()] = new TypeChoiceClass();
		listaObjectWorkers[QuestionAnalyzer.ANSWER_TYPE.NOTYPE.ordinal()] = new TypeNoTypeClass();
		if (TESTING) {
			String question = "0043 What is Czech Republic capital?";
			aq = QuestionAnalyzer.analyzeQuestion(question);
			query = new Query(aq);

			Result r = new Result(
					"The Czech Republic ,"
							+ " short form Česko Czech pronunciation:  is a landlocked country in Central Europe. The country is bordered by "
							+ "Germany to the west, Austria to the south, Slovakia to the east and Poland to the north. Its capital and largest city, with "
							+ "1.3 million inhabitants, is Prague. The Czech Republic includes the historical territories of Bohemia and Moravia and a small"
							+ " part of Silesia.", query,
					"http://en.wikipedia.org/wiki/Czech_Republic");
			// searchResults.add(r);

			r = new Result(
					"Prague, or Praha, as it is known locally, is the capital of the Czech Republic. This Central European city, inhabited by Slavs,"
							+ " influenced by Europe, and known globally as a top travel destination, is stimulating, accessible, and unforgettable. Visually, Prague "
							+ "is a smorgasbord of architectural styles and artistic details. From the paving stones underfoot to the spires on its churches, "
							+ "every element has a dual function: to serve its structural purpose and to appeal to the eye. For today's Prague, a third "
							+ "benefit of its beauty can be identified: distraction.",
					query,
					"http://goeasteurope.about.com/od/praguetravel/a/prague.htm");
			// searchResults.add(r);

			r = new Result(
					"Prague The capital and largest city of the Czech Republic, in the western part of the country on the Vltava River. "
							+ "Known since the 9th century, it was a leading cultural and commercial center by the 14th century and came under Hapsburg rule "
							+ "in 1526. Prague was the capital of Czechoslovakia from the country's formation in 1918 until its dissolution in 1993."
							+ "Population: 1,190,000.", query,
					"http://www.thefreedictionary.com/Capital+of+Czech+Republic");
			// searchResults.add(r);

		} else {
			searchResults = ResultGenerationManager.getResult();
		}

	}

	private static ArrayList<Integer> findNAMES(Result r) {

		ArrayList<Integer> namePositionList = new ArrayList<Integer>();

		int count = 0;
		for (String t : r.getTags()) {
			if (t.startsWith("NN")) {
				namePositionList.add(count);
			}
			count++;
		}
		return namePositionList;
	}
	
	
	public static ArrayList<ArrayList<Result>> getResults(){
		return rawR;
	}

}